package com.videoweb.controller;

import com.videoweb.model.UploadStatus;
import com.videoweb.model.User;
import com.videoweb.model.Video;
import com.videoweb.service.ChunkedUploadService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

@Slf4j
@RestController
@RequestMapping("/api/upload")
public class ChunkedUploadController {
    
    @Autowired
    private ChunkedUploadService chunkedUploadService;
    
    /**
     * 检查文件上传状态
     * 支持断点续传，返回已上传的分片信息
     */
    @GetMapping("/status/{fileHash}")
    public ResponseEntity<Map<String, Object>> getUploadStatus(@PathVariable String fileHash) {
        try {
            Map<String, Object> response = new HashMap<>();
            
            UploadStatus uploadStatus = chunkedUploadService.getUploadStatus(fileHash);
            
            if (uploadStatus != null) {
                Set<Integer> uploadedChunks = uploadStatus.getUploadedChunkSet();
                
                response.put("success", true);
                response.put("exists", true);
                response.put("fileHash", fileHash);
                response.put("uploadedChunks", uploadedChunks);
                response.put("totalChunks", uploadStatus.getTotalChunks());
                response.put("status", uploadStatus.getStatus().getCode());
                response.put("progress", uploadStatus.getProgressPercentage());
                response.put("completed", uploadStatus.getStatus() == UploadStatus.UploadStatusEnum.COMPLETED);
                
                if (uploadStatus.getStatus() == UploadStatus.UploadStatusEnum.COMPLETED) {
                    response.put("finalPath", uploadStatus.getFinalPath());
                }
                
                log.info("查询上传状态: fileHash={}, 已上传={}/{}, 状态={}", 
                    fileHash, uploadedChunks.size(), uploadStatus.getTotalChunks(), uploadStatus.getStatus());
                
            } else {
                response.put("success", true);
                response.put("exists", false);
                response.put("uploadedChunks", new int[0]);
                response.put("message", "文件首次上传");
                
                log.info("文件首次上传: fileHash={}", fileHash);
            }
            
            return ResponseEntity.ok(response);
            
        } catch (Exception e) {
            log.error("检查上传状态失败: fileHash={}, error={}", fileHash, e.getMessage(), e);
            
            Map<String, Object> errorResponse = new HashMap<>();
            errorResponse.put("success", false);
            errorResponse.put("error", "检查上传状态失败: " + e.getMessage());
            
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(errorResponse);
        }
    }
    
    /**
     * 上传文件分片
     * 断点续传的核心API
     */
    @PostMapping("/chunk")
    public ResponseEntity<Map<String, Object>> uploadChunk(
            @RequestParam("chunk") MultipartFile chunk,
            @RequestParam("chunkIndex") Integer chunkIndex,
            @RequestParam("totalChunks") Integer totalChunks,
            @RequestParam("fileHash") String fileHash,
            @RequestParam("fileName") String fileName,
            @RequestParam("fileSize") Long fileSize,
            @RequestParam(value = "title", required = false) String title,
            @RequestParam(value = "description", required = false) String description,
            HttpServletRequest request) {
        
        Map<String, Object> response = new HashMap<>();
        
        try {
            // 参数验证
            if (chunk.isEmpty()) {
                response.put("success", false);
                response.put("error", "分片数据为空");
                return ResponseEntity.badRequest().body(response);
            }
            
            if (chunkIndex < 0 || chunkIndex >= totalChunks) {
                response.put("success", false);
                response.put("error", "分片索引无效: " + chunkIndex);
                return ResponseEntity.badRequest().body(response);
            }
            
            if (fileHash == null || fileHash.trim().isEmpty()) {
                response.put("success", false);
                response.put("error", "文件哈希值不能为空");
                return ResponseEntity.badRequest().body(response);
            }
            
            // 获取用户信息
            Long userId = getCurrentUserId(request);
            
            log.info("接收分片上传: fileHash={}, chunk={}/{}, size={}, user={}", 
                fileHash, chunkIndex + 1, totalChunks, chunk.getSize(), userId);
            
            // 获取或创建上传状态
            UploadStatus uploadStatus = chunkedUploadService.getOrCreateUploadStatus(
                fileHash, fileName, fileSize, totalChunks, (int) chunk.getSize(), 
                userId, title, description);
            
            // 检查分片是否已上传
            Set<Integer> uploadedChunks = uploadStatus.getUploadedChunkSet();
            if (uploadedChunks.contains(chunkIndex)) {
                log.info("分片已存在，跳过上传: fileHash={}, chunkIndex={}", fileHash, chunkIndex);
                
                response.put("success", true);
                response.put("message", "分片已存在");
                response.put("chunkIndex", chunkIndex);
                response.put("uploadedChunks", uploadedChunks.size());
                response.put("totalChunks", totalChunks);
                response.put("progress", uploadStatus.getProgressPercentage());
                
                return ResponseEntity.ok(response);
            }
            
            // 保存分片文件
            chunkedUploadService.saveChunk(uploadStatus, chunkIndex, chunk);
            
            // 更新上传状态
            chunkedUploadService.markChunkUploaded(fileHash, chunkIndex);
            
            // 重新获取状态（包含最新的分片信息）
            uploadStatus = chunkedUploadService.getUploadStatus(fileHash);
            
            response.put("success", true);
            response.put("message", "分片上传成功");
            response.put("chunkIndex", chunkIndex);
            response.put("uploadedChunks", uploadStatus.getUploadedChunkSet().size());
            response.put("totalChunks", totalChunks);
            response.put("progress", uploadStatus.getProgressPercentage());
            response.put("isComplete", uploadStatus.isAllChunksUploaded());
            
            log.info("分片上传成功: fileHash={}, chunkIndex={}, progress={:.1f}%", 
                fileHash, chunkIndex, uploadStatus.getProgressPercentage());
            
            return ResponseEntity.ok(response);
            
        } catch (Exception e) {
            log.error("分片上传失败: fileHash={}, chunkIndex={}, error={}", 
                fileHash, chunkIndex, e.getMessage(), e);
            
            response.put("success", false);
            response.put("error", "分片上传失败: " + e.getMessage());
            response.put("chunkIndex", chunkIndex);
            
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(response);
        }
    }
    
    /**
     * 合并文件分片
     * 完成断点续传的最后一步
     */
    @PostMapping("/merge")
    public ResponseEntity<Map<String, Object>> mergeChunks(@RequestBody Map<String, Object> request) {
        Map<String, Object> response = new HashMap<>();
        
        try {
            String fileHash = (String) request.get("fileHash");
            String fileName = (String) request.get("fileName");
            Integer totalChunks = (Integer) request.get("totalChunks");
            Long fileSize = Long.valueOf(request.get("fileSize").toString());
            
            if (fileHash == null || fileHash.trim().isEmpty()) {
                response.put("success", false);
                response.put("error", "文件哈希值不能为空");
                return ResponseEntity.badRequest().body(response);
            }
            
            log.info("开始合并文件分片: fileHash={}, fileName={}, totalChunks={}, fileSize={}", 
                fileHash, fileName, totalChunks, fileSize);
            
            // 获取上传状态
            UploadStatus uploadStatus = chunkedUploadService.getUploadStatus(fileHash);
            if (uploadStatus == null) {
                response.put("success", false);
                response.put("error", "上传状态不存在");
                return ResponseEntity.badRequest().body(response);
            }
            
            // 验证所有分片是否上传完成
            if (!uploadStatus.isAllChunksUploaded()) {                Set<Integer> uploadedChunks = uploadStatus.getUploadedChunkSet();
                List<Integer> missingChunks = uploadStatus.getMissingChunkIndexes();
                
                log.warn("分片不完整，无法合并: fileHash={}, 已上传={}/{}, 缺少分片={}", 
                    fileHash, uploadedChunks.size(), uploadStatus.getTotalChunks(), missingChunks);
                
                response.put("success", false);
                response.put("error", String.format("分片不完整: %d/%d", 
                    uploadedChunks.size(), uploadStatus.getTotalChunks()));
                response.put("missingChunks", missingChunks.toArray());
                response.put("uploadedChunks", uploadedChunks.toArray());
                response.put("totalChunks", uploadStatus.getTotalChunks());
                response.put("progress", uploadStatus.getProgressPercentage());
                response.put("suggestion", "请重新上传文件，断点续传会自动补充缺少的分片");
                
                return ResponseEntity.badRequest().body(response);
            }
            
            // 检查是否已经完成
            if (uploadStatus.getStatus() == UploadStatus.UploadStatusEnum.COMPLETED) {
                // 创建视频记录
                Video video = chunkedUploadService.createVideoRecord(uploadStatus);
                
                response.put("success", true);
                response.put("message", "文件已存在，无需重复合并");
                response.put("fileHash", fileHash);
                response.put("filePath", uploadStatus.getFinalPath());
                response.put("videoId", video.getId());
                
                return ResponseEntity.ok(response);
            }
            
            // 执行文件合并
            String finalFilePath = chunkedUploadService.mergeChunks(uploadStatus);
            
            // 创建视频记录
            Video video = chunkedUploadService.createVideoRecord(uploadStatus);
            
            // 清理临时文件（可以考虑异步执行）
            try {
                chunkedUploadService.cleanupTempFiles(fileHash);
            } catch (Exception e) {
                log.warn("清理临时文件失败: fileHash={}, error={}", fileHash, e.getMessage());
            }
            
            response.put("success", true);
            response.put("message", "文件合并成功");
            response.put("fileHash", fileHash);
            response.put("filePath", finalFilePath);
            response.put("videoId", video.getId());
            response.put("fileSize", fileSize);
            
            log.info("文件合并成功: fileHash={}, filePath={}, videoId={}", 
                fileHash, finalFilePath, video.getId());
            
            return ResponseEntity.ok(response);
            
        } catch (Exception e) {
            log.error("文件合并失败: error={}", e.getMessage(), e);
            
            response.put("success", false);
            response.put("error", "文件合并失败: " + e.getMessage());
            
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(response);
        }
    }
    
    /**
     * 获取缺少的分片信息
     * 用于断点续传时确定需要重新上传哪些分片
     */
    @GetMapping("/missing/{fileHash}")
    public ResponseEntity<Map<String, Object>> getMissingChunks(@PathVariable String fileHash) {
        Map<String, Object> response = new HashMap<>();
        
        try {
            UploadStatus uploadStatus = chunkedUploadService.getUploadStatus(fileHash);
            
            if (uploadStatus == null) {
                response.put("success", false);
                response.put("error", "上传状态不存在");
                return ResponseEntity.badRequest().body(response);
            }            Set<Integer> uploadedChunks = uploadStatus.getUploadedChunkSet();
            List<Integer> missingChunks = uploadStatus.getMissingChunkIndexes();
            
            response.put("success", true);
            response.put("fileHash", fileHash);
            response.put("totalChunks", uploadStatus.getTotalChunks());
            response.put("uploadedChunks", uploadedChunks);
            response.put("missingChunks", missingChunks);
            response.put("progress", uploadStatus.getProgressPercentage());
            response.put("isComplete", uploadStatus.isAllChunksUploaded());
            
            log.info("获取缺少分片信息: fileHash={}, 已上传={}/{}, 缺少={}", 
                fileHash, uploadedChunks.size(), uploadStatus.getTotalChunks(), missingChunks);
            
            return ResponseEntity.ok(response);
            
        } catch (Exception e) {
            log.error("获取缺少分片信息失败: fileHash={}, error={}", fileHash, e.getMessage(), e);
            
            response.put("success", false);
            response.put("error", "获取缺少分片信息失败: " + e.getMessage());
            
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(response);
        }
    }

    // 强制合并功能暂时禁用，待修复编译问题后重新启用

    /**
     * 取消上传，清理临时文件
     */
    @DeleteMapping("/cancel/{fileHash}")
    public ResponseEntity<Map<String, Object>> cancelUpload(@PathVariable String fileHash) {
        Map<String, Object> response = new HashMap<>();
        
        try {
            UploadStatus uploadStatus = chunkedUploadService.getUploadStatus(fileHash);
            
            if (uploadStatus != null) {
                // 清理临时文件
                chunkedUploadService.cleanupTempFiles(fileHash);
                
                response.put("success", true);
                response.put("message", "上传已取消，临时文件已清理");
                
                log.info("取消上传: fileHash={}", fileHash);
            } else {
                response.put("success", true);
                response.put("message", "上传记录不存在");
            }
            
            return ResponseEntity.ok(response);
            
        } catch (Exception e) {
            log.error("取消上传失败: fileHash={}, error={}", fileHash, e.getMessage(), e);
            
            response.put("success", false);
            response.put("error", "取消上传失败: " + e.getMessage());
            
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(response);
        }
    }
    
    /**
     * 获取用户的上传历史
     */
    @GetMapping("/history")
    public ResponseEntity<Map<String, Object>> getUploadHistory(HttpServletRequest request) {
        Map<String, Object> response = new HashMap<>();
        
        try {
            Long userId = getCurrentUserId(request);
            
            if (userId == null) {
                response.put("success", false);
                response.put("error", "请先登录");
                return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(response);
            }
            
            // 这里可以实现查询用户上传历史的逻辑
            // List<UploadStatus> history = chunkedUploadService.getUserUploadHistory(userId);
            
            response.put("success", true);
            response.put("message", "功能开发中");
            
            return ResponseEntity.ok(response);
            
        } catch (Exception e) {
            log.error("获取上传历史失败: error={}", e.getMessage(), e);
            
            response.put("success", false);
            response.put("error", "获取上传历史失败: " + e.getMessage());
            
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(response);
        }
    }
    
    // ==================== 私有工具方法 ====================
    
    /**
     * 获取当前用户ID
     */
    private Long getCurrentUserId(HttpServletRequest request) {
        try {
            Object userObj = request.getSession().getAttribute("user");
            if (userObj instanceof User) {
                return ((User) userObj).getId();
            }
        } catch (Exception e) {
            log.debug("获取用户ID失败: {}", e.getMessage());
        }
        return null;
    }
    
    // 帮助方法暂时移除
} 